//                 _              
//                | |             
//   __ _ _ __ ___| |__ __  _____ 
//  / _` | '__/ __| '_ \\ \/ / __|
// | (_| | | | (__| | | |>  <\__ \
//  \__,_|_|  \___|_| |_/_/\_\___/
//                                
// Copyright 2010 Scott Dixon http://www.archxs.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package com.archxs.commons;

import java.util.Arrays;
import java.util.Locale;

import org.junit.Assert;
import org.junit.Test;

import com.archxs.commons.Variant;

/**
 * Unit test covering {@link Variant}'s array features.
 */
public class VariantArraysTest {

    @Test
    public void testNullArray() {
        final Variant nullArray = new Variant((String[])null);
        Assert.assertEquals(1, nullArray.getArrayLength());
        final String[] stringArray = nullArray.getArray(new String[0]);
        Assert.assertNotNull(stringArray);
        Assert.assertEquals(1, stringArray.length);
        Assert.assertEquals("null", stringArray[0]);
        Assert.assertEquals(1, nullArray.getArrayLength());
    }
    
    @Test
    public void testArrayLength() {
        Assert.assertEquals(1, Variant.valueOf("foo").getArrayLength());
    }
    
    @Test
    public void testArrayOrderStability() {
        final String[] v = new String[]{"one","two", "three", "four", "five"};
        final String[] variantArray = Variant.valueOf(v).getArray(new String[]{});
        Assert.assertTrue(Arrays.equals(v, variantArray));
    }
    
    @Test
    public void testSingleItemArray() {
        Assert.assertEquals("foo", Variant.valueOf(new String[]{"foo"}).toString());
        Assert.assertEquals(Variant.valueOf("foo"),Variant.valueOf(new String[]{"foo"})); 
    }
    
    @Test
    public void testToFromToFromArrayString() {
        final String[] testInput = new String[]{"one","two,three","four\\,five","six"};
        final Locale locale = Locale.CANADA;
        final String testInputMarshalled = Variant.arrayToString(testInput, locale);
        final Variant[] testInputUnMarshalled = Variant.stringToArray(Variant.class, testInputMarshalled, locale);
        Assert.assertEquals(testInput.length, testInputUnMarshalled.length);
        for(int i = 0; i < testInput.length; ++i) {
            Assert.assertEquals(testInput[i], testInputUnMarshalled[i].toString());
        }
    }
    
    @Test
    public void testToFromArrayDefault() {
        final String[] testInput = new String[]{"one","two","three","four","five","six"};
        final Variant fromArray = new Variant(testInput);
        Assert.assertEquals(testInput.length, fromArray.getArrayLength());
        Assert.assertNotNull(fromArray.toString());
        Assert.assertEquals(Arrays.toString(testInput), fromArray.toString());
        final Variant[] outputArray = fromArray.getArray();
        Assert.assertEquals(testInput.length, outputArray.length);
        for(int i = 0; i < testInput.length; ++i) {
            Assert.assertEquals(testInput[i], outputArray[i].stringValue());
        }
    }
    
    @Test
    public void testToFromArrayWithCommas() {
        final String[] testInput = new String[]{"one","two,three","four\\,five","six"};
        final Variant fromArray = new Variant(testInput);
        Assert.assertNotNull(fromArray.toString());
        Assert.assertEquals("[one, two\\,three, four\\\\,five, six]", fromArray.toString());
        final Variant[] outputArray = fromArray.getArray();
        Assert.assertEquals(testInput.length, outputArray.length);
        for(int i = 0; i < testInput.length; ++i) {
            Assert.assertEquals(testInput[i], outputArray[i].stringValue());
        }
    }
    
    @Test
    public void testToArrayFromString() {
        final String testInput = "0,1,2,3";
        final Variant fromString = new Variant(testInput);
        final Variant[] outputArray = fromString.getArray();
        Assert.assertEquals(4, outputArray.length);
        for(int i = 0; i < outputArray.length; ++i) {
            Assert.assertEquals(i, outputArray[i].intValue());
        }
    }
    
    @Test
    public void testToArrayFromStringWBrackets() {
        final String testInput = "[0,1,2,3]";
        final Variant fromString = new Variant(testInput);
        final Variant[] outputArray = fromString.getArray();
        Assert.assertEquals(4, outputArray.length);
        for(int i = 0; i < outputArray.length; ++i) {
            Assert.assertEquals(i, outputArray[i].intValue());
        }
    }
    
    @Test
    public void testToArrayFromStringThroughJavaArrays() {
        final String testInput = Arrays.toString(new int[]{0,1,2,3});
        final Variant fromString = new Variant(testInput);
        final Variant[] outputArray = fromString.getArray();
        Assert.assertEquals(4, outputArray.length);
        for(int i = 0; i < outputArray.length; ++i) {
            Assert.assertEquals(i, outputArray[i].intValue());
        }
    }
    
    @Test
    public void testUseFirstIndexInArray() {
        Assert.assertTrue(Variant.valueOf("true,false").booleanValue());
        Assert.assertEquals(2l, Variant.valueOf("2,44,34324").longValue());
        Assert.assertEquals(2l, Variant.valueOf("[2,44,34324]").longValue());
    }
    
    @Test
    public void testArrayStringNormalization() {
        Assert.assertEquals("abbra", Variant.valueOf("    [    Abbra   ,  b,  ] ").getNormalizedString());
        Assert.assertEquals("abbra", Variant.valueOf("       Abbra   ,  b ").getNormalizedString());
        Assert.assertEquals("abbra", Variant.valueOf("[Abbra]").getNormalizedString());
    }
    
}
